//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include <Core/Core.hpp>
#include "Item.hpp"
#include "Serializers.hpp"
#include <Math/Point2i.hpp>
#include <Math/Vector3f.hpp>
#include <Math/Quaternionf.hpp>


namespace Config
{
	//////////////////////////////////////////////////////////////////////////
	// Provide type specific serialization.
	template<>
	struct Serializer< Math::Point2i > : public Config::Item
	{
		Serializer( const std::string& key )
		:	Config::Item( key )
		{}

		bool				_Load( Math::Point2i& v, const JSONValue& inv )
		{
			if( inv.IsArray() )
			{
				const JSONArray&	values	=	inv.AsArray();
				v.Set( (int32_t)values[ 0 ]->AsNumber(), (int32_t)values[ 1 ]->AsNumber() );
				return true;
			}
			return false;
		}
		JSONValue*			_Save( const Math::Point2i& v ) const
		{
			JSONArray	array;
			array.push_back( new JSONValue( (double)v.X() ) );
			array.push_back( new JSONValue( (double)v.Y() ) );
			return new JSONValue( array );
		}
	};


	//////////////////////////////////////////////////////////////////////////
	// Provide type specific serialization.
	template<>
	struct Serializer< Math::Vector3f > : public Config::Item
	{
		Serializer( const std::string& key )
		:	Config::Item( key )
		{}

		bool				_Load( Math::Vector3f& v, const JSONValue& inv )
		{
			if( inv.IsArray() )
			{
				const JSONArray&	values	=	inv.AsArray();
				v.Set( (float)values[ 0 ]->AsNumber(), (float)values[ 1 ]->AsNumber(), (float)values[ 2 ]->AsNumber() );
				return true;
			}
			return false;
		}
		JSONValue*			_Save( const Math::Vector3f& v ) const
		{
			JSONArray	array;
			array.push_back( new JSONValue( (double)v.X() ) );
			array.push_back( new JSONValue( (double)v.Y() ) );
			array.push_back( new JSONValue( (double)v.Z() ) );
			return new JSONValue( array );
		}
	};


	//////////////////////////////////////////////////////////////////////////
	// Provide type specific serialization.
	template<>
	struct Serializer< Math::Quaternionf > : public Config::Item
	{
		Serializer( const std::string& key )
		:	Config::Item( key )
		{}

		bool				_Load( Math::Quaternionf& v, const JSONValue& inv )
		{
			if( inv.IsArray() )
			{
				const JSONArray&	values	=	inv.AsArray();
				v.Set( (float)values[ 0 ]->AsNumber(), (float)values[ 1 ]->AsNumber(), (float)values[ 2 ]->AsNumber(), (float)values[ 3 ]->AsNumber() );
				return true;
			}
			return false;
		}
		JSONValue*			_Save( const Math::Quaternionf& v ) const
		{
			JSONArray	array;
			array.push_back( new JSONValue( (double)v.X() ) );
			array.push_back( new JSONValue( (double)v.Y() ) );
			array.push_back( new JSONValue( (double)v.Z() ) );
			array.push_back( new JSONValue( (double)v.W() ) );
			return new JSONValue( array );
		}
	};
}
